/**
 * Copyright 2009-2010 - YangJiandong(chunquedong)
 * 
 * This file is part of ChunMap project
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
 * 你可以自由复制、传播本项目的下载包文件，但必须保持其完整性。
 * 我们不用对使用中的风险及由此造成的损失承担任何责任。
 * 详细情况请见《ChunMap许可协议》。

 * 想了解更多有关ChunMap的信息，请访问http://code.google.com/p/chunmap/
 */
package chunmap.model.relate.relateop;

import static chunmap.model.relate.IntersectionMatrix.*;
import chunmap.model.coord.Position;
import chunmap.model.elem.CoordSeqEditor;
import chunmap.model.elem.LineSegment;
import chunmap.model.geom.Geometry;
import chunmap.model.geom.LineString;
import chunmap.model.geom.Ring;
import chunmap.model.geom.Polygon;
import chunmap.model.relate.ComputeIm;

/**
 * disjion,touch,over,within,onBoundary
 * 
 * @author chunquedong
 * 
 */
class LineString_LinearRing extends ComputeIm {

	public LineString_LinearRing(LineString l1, Ring r2) {
		g1 = l1;
		g2 = r2.toPolygon();
	}

	private boolean cross = false;// 是否有交叉
	private boolean within = false;// 被包含

	@Override
	protected int inner2innerDim(Geometry g1, Geometry g2) {
		LineString l1 = (LineString) g1;
		Ring r2 = ((Polygon) g2).getShell();
		// 线和环边界分离
		if (im.get(Inner, Border) == EmptyDim
				&& im.get(Border, Border) == EmptyDim) {
			if (r2.containIn(l1.firstPoint())) {
				within = true;
				return LineDim;
			}
			return EmptyDim;
		}
		// 是否有十字交叉
		if (_hasCross(r2,l1)) {
			cross = true;
			return LineDim;
		}
		// 用自己的折点将线串打断
		CoordSeqEditor tLine = new CoordSeqEditor(l1.getPoints());
		for (int i = 0, n = r2.size(); i < n; i++) {
			Position p = r2.getPoint(i);
			tLine.tryInsertPoint(p);
		}
		// 片段在里面
		for (int i = 0, n = tLine.size() - 1; i < n; i++) {
			LineSegment lseg = tLine.getLineSegment(i);
			Position mp = lseg.getMiddlePoint();
			if (r2.containIn(mp) && !r2.onLineString(mp)) {
				return LineDim;
			}
		}
		return EmptyDim;
	}

	@Override
	protected boolean within(Geometry g1, Geometry g2) {
		if (within)
			return true;
		if (cross)
			return false;

		LineString l1 = (LineString) g1;
		Ring r2 = ((Polygon) g2).getShell();
		if (r2.containLineStringIn(l1))
			return true;

		return false;
	}

	public boolean _hasCross(LineString me,LineString l1) {
		LineString l2 = me;
		for (int i = 0, n = l1.size() - 1; i < n; i++) {
			for (int j = 0, n2 = l2.size() - 1; j < n2; j++) {
				LineSegment s1 = l1.getLineSegment(i);
				LineSegment s2 = l2.getLineSegment(j);
				Object g = s1.intersection(s2);
				if (g == null) {
					continue;
				} else if (g instanceof Position) {
					Position p = (Position) g;
					if (!isSegmentBorder(s1, s2, p)) {
						return true;
					}
				}
			}
		}
		return false;
	}

	// 鏄竟鐣岀偣
	private boolean isSegmentBorder(LineSegment l1, LineSegment l2, Position p) {
		return p.approximateEquals(l1.getStartPoint())
				|| p.approximateEquals(l1.getEndPoint())
				|| p.approximateEquals(l2.getStartPoint())
				|| p.approximateEquals(l2.getEndPoint());
	}


}
